# coding: utf-8
'''
Created on 4 jul 2013

@author: Nils Amiet
'''



import unittest
import os, sys

''' Required for running the script from anywhere outside eclipse'''
os.chdir(os.path.dirname(os.path.realpath(__file__)))
sys.path.append('..')

from SentiStrength.sentistrength import SentiStrength
from Tools.Timer import Timer
from ITInfluence.language import isEnglishTweet
from ITInfluence.polarity import PolarityCounter



class SentiStrengthTest(unittest.TestCase):
    '''Tests for SentiStrength'''
    
    def testPerformance(self):
        line = "Even though it looked good at first, this movie is utterly bad."
        text = line
        textCount = 16000 # claims to annotate 16k texts in a second
        for unused in range(textCount):
            text += "\n" + line
        
        timer = Timer()
        timer.start()
        s = SentiStrength()
        unused = s.classifiy(text)
        timer.stop()
        
        # Allow some margin because 16k is not many, it works best with larger amounts.
        # For instance with 160k the relative margin is much smaller.
        margin = 1000
        expectedTime = 1000 + margin 
        experimentalValue = timer.totalTimeMillis <= expectedTime
        expectedValue = True
        errorMessage = "Took %s millis." % timer.totalTimeMillis
        
        self.assertEqual(experimentalValue, expectedValue, errorMessage)
        
class LanguageTest(unittest.TestCase):
    '''Tests for the language filter module'''
    
    def testTexts(self):
        texts = [
                 (False, "Je me promène le long de la côte sud-ouest de l'afrique"),
                 (True, "I live in New York because I think it's the most beautiful city in the world"),
                 (False, "Je t'aime"),
                 (True, "I love you"),
                 # English tweets
                 (True, "RT @bidon Beau gave Luke a hickey.. Really shouldn't be jealous..@BrooksBeau @luke_brooks WANT ONE:( http://t.co/0uBKDDZSIB"),
                 (True, "#GGM I love socks too ,me Too. @AHuston_FanPage @NicolasCageFake @elderkeeper @AlbusDumby7 @mondesdegwenn @J0HNNYDepp http://t.co/OsTX4MdxvY"),
                 (True, "RT @mashable: Don't Bother Following the Fiat Abarth 500 (@Abarth500_DE) on Twitter — It's Too Damn Fast http://t.co/5XopBSt4IS #innovative"),
                 # Foreign tweets
                 (False, "Amacın 2 tane ağaçtan çok daha derin olduğu ortada ama TR bölünmez! @yigitbulutt http://t.co/7t3vHf7VDd"),
                 (False, "RT @MlaniX1: Voila la photo pour vous remercier grâce a vous je suis a plus de 500 followers merci beaucoup &lt;3 http://t.co/Uv5YXmPuvM"),
                 (False, "RT @ta9ton: 不覚にもイオン閉店に間に合わず隔離された僕は… http://t.co/zRnOnpTFVN"),
                 ]
        
        # We'd like to have the full debug in case more than one text fails
        exception = None
        
        for expectedValue, text in texts:
            experimentalValue = isEnglishTweet(text)
            errorMessage = "False classification of text %s" % text
            try:
                self.assertEqual(expectedValue, experimentalValue, errorMessage)
            except Exception as e:
                print(e)
                exception = e
                
        if exception is not None:
            raise exception
        
class PolarityTests(unittest.TestCase):
    '''Tests for polarity counting'''
    
    def setUp(self):
        r1 = {"from": 4, "to": 5, "polarity": 0.8}
        r2 = {"from": 5, "to": 4, "polarity": 0.2}
        r3 = {"from": 4, "to": 2, "polarity": -0.3}
        r4 = {"from": 2, "to": 5, "polarity": 0.1}
        self.replies = [r1, r2, r3, r4]
    
    def testPolarity(self):
        polarityCounter = PolarityCounter(self.replies)
        ranking = polarityCounter.polarityDifferenceRanking()
        
        experimentalValue = ranking[0][0]
        # node 2 should be first because it has the greatest polarity difference
        expectedValue = 2
        errorMessage = "Incorrect ranking. User %s should be first" % expectedValue
                
        self.assertEqual(experimentalValue, expectedValue, errorMessage)
        
    def testNDI(self):
        polarityCounter = PolarityCounter(self.replies)
        
        experimentalValue = polarityCounter.NDI
        # NDI = sum of squares of differences
        #     = (0.5)^2 + (0.5)^2 + (1.0)^2
        #     = 0.25 + 0.25 + 1
        #     = 1.5
        expectedValue = 1.5
        errorMessage = "Wrong NDI value. Expected: %s, experimental: %s" % (expectedValue, experimentalValue)
        
        self.assertEqual(experimentalValue, expectedValue, errorMessage)

if __name__ == "__main__":
    unittest.main()